#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <thread>    // 引入线程库
#include <atomic>    // 用于控制线程的标志

std::atomic<bool> running(true); // 控制线程的标志，用于启动和停止线程

int openPort(const char * dev_name)
{
    int fd; 
    fd = open(dev_name, O_RDWR | O_NOCTTY | O_NDELAY);
    if(fd == -1)
    {
        printf("open_port: 无法打开 %s. \n", dev_name); 
    }
    else
    {
        fcntl(fd, F_SETFL, 0);
        printf("串口已打开.\n");
    }
    return(fd);
}

int configurePort(int fd)
{
    struct termios port_settings;               
    cfsetispeed(&port_settings, B115200);       //设置波特率
    cfsetospeed(&port_settings, B115200);

    port_settings.c_cflag &= ~PARENB;           
    port_settings.c_cflag &= ~CSTOPB;           
    port_settings.c_cflag &= ~CSIZE;            
    port_settings.c_cflag |= CS8;               

    if(tcsetattr(fd, TCSANOW, &port_settings) != 0)
    {
        perror("配置串口错误");
        return -1;
    }
    return(fd);
}

bool sendXYZ(int fd, double * xyz)
{
    unsigned char send_bytes[] = { 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE}; 
    if(NULL == xyz)
    {
        if (8 == write(fd, send_bytes, 8)) 
            return true; 
        return false; 
    }
    short * data_ptr = (short *)(send_bytes + 1); 
    data_ptr[0] = (short)xyz[0];
    data_ptr[1] = (short)xyz[1];
    data_ptr[2] = (short)xyz[2];
    if (8 == write(fd, send_bytes, 8))      
        return true; 
    return false; 
}

// 接收数据函数
void readData(int fd)
{
    unsigned char buffer[8];
    int bytes_read;
    bool syncing = true;

    while(running)
    {
        if(syncing)
        {
            printf("1");
            bytes_read=read(fd,buffer,1);
            if(bytes_read==1 && buffer[0]==0xFF)
            {
                syncing=false;
            }
            else
            {
                usleep(1000);
                continue;
            }
        }
        bytes_read=read(fd,buffer+1,7);
        if(bytes_read==8&&buffer[7]==0xFE)
        {
            double received_number;
            memccpy(&received_number,buffer+1,6,sizeof(received_number));
            printf("接收到的数据：%f\n",received_number);
            syncing=true;
        }
        else
        {
            printf("错误：数据包不完整或格式不正确\n");
            syncing=true;
        }
    }


}

void continuousSend(int fd)
{
    double xyz[] = {10.5, 20.7, 30.2}; // 示例发送数据
    while (running)
    {  // 持续发送数据
        if (sendXYZ(fd, xyz))
        {
            printf("发送数据: XYZ = (%f, %f, %f)\n", xyz[0], xyz[1], xyz[2]);
        } 
        else
        {
            printf("数据发送失败\n");
        }
        usleep(1000000);  // 控制发送频率（1秒发送一次）
    }
}

int main()
{
    int fd = openPort("/dev/ttyUSB0"); // 替换为您的串口设备
    if (fd == -1)
    {
        printf("无法打开串口\n");
        return -1;
    }

    if (configurePort(fd) == -1)
    {
        printf("无法配置串口\n");
        close(fd);
        return -1;
    }

    // 创建接收和发送线程
    std::thread receiver(readData,fd);
    std::thread sender(continuousSend, fd);

    // 等待用户按下 Enter 键来停止程序      readDate

    printf("按 Enter 键停止程序...\n");
    getchar();

    // 停止标志设置为 false
    running = false;

    // 等待线程结束
    
    sender.join();
    receiver.join();

    // 关闭串口
    close(fd);

    return 0;
}